<template>
  <div class="page-table">
    <div class="page-table-header-query-form" v-if="searchData.length>0">
      <query-form
        :search-data="searchData"
        :query-param="queryParam"
        @search="handleSearch"
        :col-span="colSpan"
      >
        <template v-for="data in searchDataCustom" :slot="data.customRender">
          <slot :name="data.customRender"></slot>
        </template>
      </query-form>
    </div>
    <a-card :bordered="false">
      <div class="page-table-header-wrapper">
        <a-row class="page-table-header-operate" v-if="showTableHeader">
          <a-col :xs="24" :md="18">
            <div class="page-table-header-button-group">
              <slot name="addBtn" v-if="showAddButton">
                <a-button type="primary" icon="plus" @click="onAddClick">新增</a-button>
              </slot>
              <slot name="extraBtn"></slot>
              <slot name="delBtn" v-if="showDeleteButton">
                <a-button
                  icon="delete"
                  type="danger"
                  v-show="selectedRowKeys.length>0"
                  :disabled="disabledDeleteButton"
                  @click="onDeleteClick"
                >删除</a-button>
              </slot>
            </div>
          </a-col>
          <a-col :xs="24" :md="6">
            <tool-bar
              :size="tableSize"
              :tool-bar="toolBar"
              :screenColumn="columns"
              :export-button-loading="exportButtonLoading"
              @onReloadClick="reload"
              @onExportClick="onExportClick"
              @onScrrenChange="onScrrenChange"
              @onSizeChange="onSizeChange"
            ></tool-bar>
          </a-col>
        </a-row>
      </div>
      <div class="page-table-content">
        <a-table
          ref="pageTable"
          :columns="tableColumns"
          :rowKey="record=>record[rowKey]"
          :dataSource="tableData"
          :pagination="pagination"
          :row-selection="rowSelection"
          :bordered="bordered"
          :loading="loading"
          :size="tableSize"
          @change="onTableChange"
        >
          <slot></slot>
          <!-- 自定义表格渲染项 -->
          <template
            v-for="colCustom in columnsCustom"
            :slot="colCustom.customRender"
            slot-scope="text,record"
          >
            <slot :name="colCustom.customRender" :text="text" :record="record"></slot>
          </template>
        </a-table>
      </div>
    </a-card>
  </div>
</template>
<script>
import request from "@/utils/request";
import { downloadFile } from "@/utils/file";
import ToolBar from "@/components/PageTable/component/toolBar";
//分页配置
const pagination = {
  pageSize: 10, // 默认每页显示数量
  showSizeChanger: true, // 显示可改变每页数量
  pageSizeOptions: ["10", "20", "50", "100"], // 每页数量选项
  showTotal: (total) => `共${total}条`, // 显示总数
  total: 0, //总条数
  current: 1,
  buildOptionText: (pageSizeOptions) => `${pageSizeOptions.value}条/页`,
};
//显示行号
const lineNoArr = [
  {
    title: "序号",
    width: "70px",
    align: "center",
    customRender: (text, record, index) => {
      return pagination.pageSize * (pagination.current - 1) + index + 1;
    },
  },
];

export default {
  components: { ToolBar },
  props: {
    columns: {
      //为了兼容template风格传参方式 我们columns可以不作为必传值使用
      type: Array,
    },
    //列的主键（强制必填）
    rowKey: {
      type: String,
      required: true,
    },
    size: {
      type: String,
      default: "small",
    },
    //查询类型 可分为page 和list
    queryType: {
      type: String,
      default: "page",
    },
    //查询请求 查询数据api
    queryApi: {
      type: String,
      required: true,
    }, //删除api
    deleteApi: {
      type: String,
    },
    //导出api
    exportApi: {
      type: String,
    },
    //是否增加边框
    bordered: {
      type: Boolean,
      default: false,
    }, //选择类型
    selection: {
      default: "multiple", //single(单选) null(不显示)
    },
    //搜索的data 可支持 input select date //todo根据需要进行持续增加 [{name,type,label}]
    searchData: {
      type: Array,
      default: () => [],
    },
    //查询参数
    queryParam: {
      type: Object,
      default: () => {
        return {};
      },
    },
    colSpan: {
      type: Number,
      default: 6,
    },
    //新增按钮进入添加详情页，注意这不是打开弹窗页面，弹窗页面需要宁外的逻辑，我们会触发一个事件以供多样化设置
    addFormUrl: {
      type: String,
    },
    //是否显示新增按钮 默认显示 (方便外面做权限控制，如果新增按钮使用默认按钮的话)(此处控制为v-if)
    showAddButton: {
      type: Boolean,
      default: true,
    },
    //是否显示删除按钮 默认显示 (方便外面做权限控制，如果删除按钮使用默认按钮的话)(此处控制为v-if)
    showDeleteButton: {
      type: Boolean,
      default: true,
    },
    //右侧头部显示toolbar
    toolBar: {
      type: Array,
      default: () => {
        return ["reload", "size", "screenList"];
      },
    }, //是否显示行号
    showLineNo: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      loading: false,
      exportButtonLoading: false,
      tableColumns: undefined,
      tableData: [],
      selectedRowKeys: [], //选中的rowKeys
      selectedRecord: [], //选中的数据
      disabledDeleteButton: false,
      pagination,
      tableSize: this.size,
    };
  },
  created() {
    this.init();
  },
  methods: {
    //初始化配置
    init() {
      if (this.columns) {
        //筛选隐藏列
        let filterHiddenArr = [
          ...this.columns.filter((column) => {
            return column.hidden !== true;
          }),
        ];
        //是否显示行号
        this.tableColumns = this.showLineNo
          ? lineNoArr.concat(filterHiddenArr)
          : filterHiddenArr;

        //判断是否有默认排序列
        let arr = this.columns.filter((item) => item.defaultSortOrder);
        if (arr.length > 0) {
          this.queryParam.orders = {
            field: arr[0].dataIndex,
            order: arr[0].defaultSortOrder,
          };
        }
      }
      //判断是否加载分页数据
      if (!this.isPageTable) this.pagination = false;
      this.loadTableData();
    },
    //------------------------------------------------------------------------表格内置方法--------------------------------------------------------------
    //查询page数据
    loadTableData() {
      if (this.isPageTable) {
        this.queryParam.page = this.pagination.current;
        this.queryParam.limit = this.pagination.pageSize;
      }
      this.loading = true;
      request
        .get(this.queryApi, { params: this.queryParam })
        .then((response) => {
          let _data = response.data.data;
          if (this.isPageTable) {
            this.tableData = [..._data.list];
            this.pagination.total = _data.totalRow;
          } else {
            this.tableData = [..._data];
          }
        })
        .catch(() => {
          this.tableData = [];
        })
        .finally(() => {
          this.loading = false;
        });
    },
    //表格重新加载
    reload() {
      this.onSelectChange([], []); //重载时清空表格选中
      this.loadTableData();
    },
    //删除选中的数据 deleteData 被删除的数据 默认删除数据是传入这一列数据
    deleteSelectData(deleteData) {
      let _self = this;
      this.$confirm({
        title: "提示",
        content: "点击确认按钮将删除这" + deleteData.length + "条数据",
        onOk() {
          _self.disabledDeleteButton = true; //禁用删除按钮
          request.post(_self.deleteApi, deleteData).then((response) => {
            _self.reload();
            _self.disabledDeleteButton = false;
          });
        },
      });
    },
    //导出excel
    exportEXcel() {
      this.exportButtonLoading = true;
      //做导出
      request
        .get(this.exportApi, {
          params: this.queryParam,
          responseType: "blob",
        })
        .then((response) => {
          let reader = new FileReader();
          reader.readAsText(new Blob([response.data]));
          reader.onload = (e) => {
            //判断接口是否返回失败信息
            if (e.target.result.indexOf("code") !== -1) {
              this.$message.error(JSON.parse(e.target.result).msg);
            } else {
              downloadFile({
                fileName: decodeURI(response.headers.filename),
                blob: response.data,
              });
            }
          };
        })
        .catch((error) => {
          console.log(error);
        })
        .finally(() => {
          this.exportButtonLoading = false;
        });
    }, //筛选列时
    onScrrenChange(checkedColumns) {
      let arr = this.columns.filter((column) => {
        return checkedColumns.indexOf(column.dataIndex) != -1;
      });
      this.tableColumns = this.showLineNo ? lineNoArr.concat(arr) : [...arr];
    },
    //表格大小变化时
    onSizeChange(size) {
      this.tableSize = size;
    },
    //表格搜索
    handleSearch() {
      this.reload();
      this.$emit("search");
    },
    //------------------------------------------------------------------------表格事件--------------------------------------------------------------
    //表格发生变化时（分页 排序 过滤）
    onTableChange(pagination, filters, sorter) {
      //处理分页信息修改
      this.pagination.current = pagination.current;
      this.pagination.pageSize = pagination.pageSize;
      //处理排序信息 sorter.order属性可能没有
      if (sorter.field && sorter.order) {
        this.queryParam.orders = { field: sorter.field, order: sorter.order };
      } else {
        this.$delete(this.queryParam, "orders");
      }
      console.log(pagination, filters, sorter);
      this.reload();
    },
    //选择表格某一列触发
    onSelectChange(selectedRowKeys, selectRecord) {
      this.selectedRowKeys = selectedRowKeys;
      this.selectedRecord = selectRecord;
      this.$emit("selectChange", selectedRowKeys, selectRecord);
    },
    //新增时操作 有新增url则执行页面跳转 没有发送新增事件
    onAddClick() {
      if (this.addFormUrl) {
        this.$router.push({ path: this.addFormUrl });
      } else {
        this.$emit("addClick");
      }
    },
    //删除时操作 有删除api则调用删除方法 没有发送删除事件 携带选中的keys数组 以及选中的数据数组
    onDeleteClick() {
      if (this.selectedRecord.length == 0) {
        this.$message.warning("你需要选择要删除的数据");
        return false;
      }
      if (this.deleteApi) {
        this.deleteSelectData(this.selectedRecord);
      } else {
        this.$emit("deleteClick", this.selectedRowKeys, this.selectedRecord);
      }
    },
    //数据导出操作
    onExportClick() {
      if (this.exportApi) {
        this.exportEXcel();
      } else {
        this.$emit("onExportClick");
      }
    },
    //------------------------------------------------------------------------对外API--------------------------------------------------------------
    //对外API 得到选中的keys
    getSelectRowKeys() {
      return this.selectedRowKeys;
    },
    //对外API 得到选中的数据
    getSelectRecords() {
      return this.selectedRecord;
    },
    //对外API 得到表格中的数据
    getDataSource() {
      return this.$refs.pageTable.dataSource;
    },
  },
  computed: {
    rowSelection() {
      if (this.selection == "multiple") {
        return {
          selectedRowKeys: this.selectedRowKeys,
          onChange: this.onSelectChange,
        };
      } else {
        return null;
      }
    },
    showTableHeader() {
      return (
        this.showAddButton ||
        this.showDeleteButton ||
        this.$slots.extraBtn ||
        this.toolBar.length > 0
      );
    },
    //判断是否为pageTable
    isPageTable() {
      return this.queryType === "page";
    },
    columnsCustom() {
      return this.columns
        ? this.columns
            .filter((item) => {
              return item.scopedSlots;
            })
            .map((item) => item.scopedSlots)
        : null;
    },
    searchDataCustom() {
      return this.searchData
        ? this.searchData
            .filter((item) => {
              return item.scopedSlots;
            })
            .map((item) => item.scopedSlots)
        : null;
    },
  },
  watch: {
    size(val) {
      this.tableSize = val;
    },
  },
};
</script>

<style lang="less" scoped>
.page-table-header-query-form {
  margin-bottom: 16px;
  padding: 24px 24px 0;
  background: #fff;
}
.page-table-header-button-group /deep/ .ant-btn {
  margin-right: 10px;
  margin-bottom: 10px;
}
</style>
